home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_100 / 132_01 / canew.c < prev    next >
Text File  |  1985-08-19  |  21KB  |  856 lines

  1. /*    Starting module of Tiny c compiler by Ron Cain    */
  2. /* Modified Feb. 10,1981 per P.L. Woods article in DDJ #52 */
  3. /*     Functions newfunc and getarg(t)    affected    */
  4. /*
  5.     DEC 25,1981    repaired break function, module ca.c
  6.  
  7.     May 5,1982    Modified declloc(typ) not to update the
  8.     the stack until all allocations have been performed . See
  9.     Doctor Dobb's #67 (May, 1982) in the letters column.
  10.  
  11.     July 10,1982    Re-repaired break function. Use of "==" instead
  12.     of "=" in "ptr = readwhile() " if statement was problem.
  13.  
  14.     July 13,1982    Changed stack offset in getarg(t) for character
  15.     variable from 0 to +1 due to byte swap between 8080 and 6809
  16.     machines.
  17.  
  18. */
  19. /* Other modules are     CDEF.C    Definitions        */
  20. /*            CB.C    Midsection of compiler    */
  21. /*            CD.C    End section of compiler */
  22. #INCLUDE CDEF.H
  23. /* */
  24. /*                            */
  25. /*    Start CC1                    */
  26. /*                            */
  27. /* Compiler begins execution here            */
  28. /*                            */
  29. main()
  30.     {
  31.     glbptr    =startglb;    /* clear global symbols */
  32.     locptr=startloc;    /* clear local symbols    */
  33.     wqptr=wq;        /* clear while queue    */
  34.     macptr=            /* clear the macro pool    */
  35.     litptr=            /* clear the literal pool*/
  36.     sp =            /* stack ptr (relative)    */
  37.     errcnt=            /* no errors (yet)    */
  38.     eof =            /* not end of file    */
  39.     input =            /* no input file    */
  40.     input2 =        /* or include file    */
  41.     output =        /* no open units    */
  42.     ncmp =            /* no open compound stmt*/
  43.     lastst =        /* no last statement    */
  44.     quote[1]=
  45.         0;    /*   all set = to zero        */
  46.     quote[0]='"';        /* fake a quote literal    */
  47.     cmode=1;        /* enable preprocessing    */
  48. /*                            */
  49. /*    Compile body                    */
  50. /*                            */
  51.     ask();            /* get user options    */
  52.     openout();        /* get an output file    */
  53.     openin();        /* and initial input file */
  54.     header();        /* intro code        */
  55.     parse();        /* process all input    */
  56.     dumplits();        /* dump literal pool    */
  57.     dumpglbs();        /* and all static memory*/
  58.     inclrn();        /* Bring in the run time package */
  59.     errorsummary();        /* summarize errors    */
  60.     trailer();        /* follow-up code    */
  61.     closeout();        /* close the output file (if any) */
  62.     return ;        /* exit to system        */
  63. }
  64. /*     Process all input text        */
  65. /* */
  66. /* At this level, only static declarations,defines,includes,    */
  67. /* and function definitions are legal...            */
  68. parse()
  69.     {
  70.     while    (eof==0)        /* do until no more input */
  71.         { 
  72.         if(amatch("char",4)){declglb(cchar);ns();}
  73.         else    if(amatch("int",3)){declglb(cint);ns();}
  74.         else    if(match("#ASM"))doasm();
  75.         else    if(match("#INCLUDE")) doinclude();
  76.         else    if(match("#DEFINE"))addmac();
  77.         else    newfunc();
  78.         blanks();        /*force eof if pending */
  79.         }
  80.     }
  81. /*                    */
  82. /*    Dump the literal pool        */
  83. /*                    */
  84. dumplits()
  85.     {
  86.     int    j,k;
  87.     if (litptr==0) return;        /* if nothing there, exit. */
  88.     printlabel(litlab);col();    /* print literal label    */
  89.     k=0;                /* init an index ...    */
  90.     while (k<litptr)        /* to loop with        */
  91.         {
  92.         defbyte();        /* pseudo-op to define byte */
  93.         j=10;            /* max bytes per line    */
  94.         while(j--)
  95.         {
  96.         outdec((litq[k++]&127));
  97.         if ((j==0) || (k>=litptr))
  98.             {
  99.             nl();        /* need carriage return    */
  100.             break;
  101.             }
  102.         outbyte (',');        /* separate bytes    */
  103.         }
  104.     }
  105. }
  106. /*    Dump all static variables    */
  107. /*                    */
  108. /*                    */
  109. dumpglbs()
  110.     {
  111.     int    j;
  112.     if (glbflag==0) return;        /* no dump if user said no */
  113.     cptr=startglb;
  114.     while(cptr<glbptr) {
  115.         if (cptr[ident]!=function)
  116.             /* do if anything but function */
  117.             { outstr(cptr);col(); /* output name as label..*/
  118.             defstorage();    /* define storage */
  119.             j=((cptr[offset]&255)+((cptr[offset+1]&255)<<8)); /* calculate number of bytes */
  120.             if ((cptr[type]==cint)||(cptr[ident]==pointer))
  121.                 j=j+j;
  122.             outdec(j);    /* neeed that many bytes */
  123.             nl();
  124.             }
  125.         cptr=cptr+symsiz;
  126.         }
  127.     }
  128. /* */
  129. /*    Report errors to user    */
  130. /* */
  131. errorsummary()
  132.     {            /* see if anything left hanging */
  133.     if (ncmp) error ("missing closing bracket");
  134.         /* Open compound statment */
  135.     nl();
  136.     comment();
  137.     outdec(errcnt);        /* total number of errors */
  138.     outstr (" errors in compilation.");
  139.     nl();
  140.     }
  141. /* */
  142. /*    Get options from user    */
  143. /* */
  144. ask()
  145.     { 
  146.     int    k,num[1];
  147.     kill();            /* clear input line */
  148.     outbyte(12);        /* clear the screen */
  149.     nl();nl();nl();        /* print banner        */
  150.     pl(" small c compiler by Ron Cain ");
  151.     nl();
  152.     /* see if the user wants to interleave the c text */
  153.     /* in the form of comments for clarity.           */
  154.     pl("Do you want the c-text to appear?");
  155.     gets(line);        /*retreive answere */
  156.     ctext=0;        /* assume no       */
  157.     if ((ch()=='Y')||(ch()=='y'))
  158.         ctext =1;    /* user said yes   */
  159.     /* see if the user wants to allocate static variables by name in this module */
  160.         pl(" Do you want the globals to be defined? ");
  161.         gets(line);
  162.         glbflag=0;
  163.         if((ch()=='Y'||ch()=='y'))
  164.             glbflag = 1;
  165.     /* get the first allowable number for compiler-generated labels */
  166.     while(1)
  167.         {pl(" Starting number for labels?" );
  168.         gets(line);
  169.         if(ch()==0) {num[0]=0; break;}
  170.         if(k=number(num)) break;
  171.         }
  172.     nxtlab=num[0];
  173.     litlab=getlabel();    /* first label = literal pool */
  174.     kill();            /* erase line              */
  175.     }
  176. /* */
  177. /*    Get output file name        */
  178. /* */
  179. openout()
  180.     {
  181.     char    *ioptr;
  182.     kill();        /* erase line    */
  183.     output = 0;        /* start with none    */
  184.     pl("Output filename?"); /* ask  ....        */
  185.     gets(line);        /* get filename        */
  186.     if(ch()==0)return;    /* none given        */
  187.     ioptr=line;        /* copy of line pointer    */
  188.     if((output=fcreat(line,iobuf0))==EOF)    /* if given, open it up */
  189.         {output =0;        /* cannot open file */
  190.         error(" Open failure ");
  191.         }
  192.     kill();                /* erase line       */
  193.     }
  194. /* */
  195. /*    Get (next) input file    */
  196. /* */
  197. openin()
  198.     {
  199.     char *testptr;
  200.     input=0;        /* none to start with */
  201.     while (input==0)    /* any above 1 allowed */
  202.         {kill();    /* clear any line    */
  203.         if(eof)break;    /* if user said none    */
  204.         pl("Input filename?");
  205.         gets(line);
  206.         testptr=line;
  207.         if(ch()==0){eof=1;break;} /* none given ... */
  208.         if((input=fopen(line,iobuf1))==EOF)
  209.             {input=0;    /* cannot open it */
  210.             pl ("Open failure");
  211.             }
  212.         }
  213.     kill();            /* erase line        */
  214.     }
  215. /* */
  216. /*    Open an include file        */
  217. /* */
  218. doinclude()
  219.     {blanks();        /* skip over to name    */
  220.     if((input2=fopen(line+lptr,iobuf2))==EOF) {
  221.         input2=0;
  222.         error("Open failure on include file");
  223.         }
  224.     kill();            /* clear rest of line    */
  225.                 /* so next read will come from new file (if open)    */
  226.     }
  227. /*    Close the output file    */
  228. closeout()
  229.     {if(output){fflush(iobuf0);fclose(iobuf0);};    /* if open,close it     */
  230.     output=0;            /* and mark it closed    */
  231.     }
  232. /* */
  233. /*    Declare a static variable (ie, define it for use)    */
  234. /*  Makes an entry in the symbol table so subsequent references can call symbol by name */
  235. /* */
  236. declglb(typ)
  237.     int    typ;
  238.     {
  239.     int    k,j;
  240.     char    sname[namesize];
  241.     while(1)
  242.         {while(1)
  243.             {if(endst())return;    /* do line    */
  244.             k=1;            /* assume one element */
  245.             if(match("*"))        /* pointer ?    */
  246.                 j=pointer;    /* yes        */
  247.             else    j=variable;    /* not a pointer*/
  248.             if(symname(sname)==0)    /* name ok ?    */
  249.                 illname();    /* illegal name */
  250.             if(findglb(sname))    /* already there? */
  251.                 multidef(sname);/* multiple def.*/
  252.             if(match("["))        /* array ?    */
  253.                 { k=needsub();    /* get size    */
  254.                 if(k) j=array;    /* 10 = array    */
  255.                 else j=pointer;    /* 0 = pointer    */
  256.                 }
  257.             addglb(sname,j,typ,k);    /* add symbol    */
  258.             break;
  259.             }
  260.         if (match(",")==0) return;    /* more ?    */
  261.         }
  262.     }
  263. /* */
  264. /*    Declare local variables (i.e.,define for use)        */
  265. /* Works just like "declglb" but modifies machine stack and adds sumbol table entry with appropriate */
  266. /* stack offset to find it again                */
  267. /* */
  268. /*
  269.     Modified to not update the stack on declaration until the
  270.    entire argument list has been parsed. See DDJ #67 in letters column.
  271. */
  272. declloc(typ)                /* type is cchar or cint */
  273.     int typ;
  274.     {
  275.     int    k,j,newsp;
  276.     char    sname[namesize];
  277. /*    Init the temp stack pointer */
  278.     newsp = sp;
  279.     while(1)
  280.         {
  281.             if(endst())break;
  282.             if(match("*"))
  283.                 j=pointer;
  284.             else    j=variable;
  285.             if(symname(sname)==0)
  286.                 illname();
  287.             if(findloc(sname))
  288.                 multidef(sname);
  289.             if(match("[")) {
  290.                 k=needsub();
  291.                 if(k)
  292.                     {j=array;
  293.                     if(typ==cint) k=k+k;
  294.                     }
  295.                 else {
  296.                     j=pointer;
  297.                     k=2;
  298.                      }
  299.                 }
  300.             else
  301.                 if((typ==cchar)&&(j!=pointer))
  302.                     k=1;
  303.                 else    k=2;
  304.             /*